package com.hxx.common.core.wcontour.util;


import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.map.FeatureLayer;
import org.geotools.map.Layer;
import org.geotools.map.MapContent;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.renderer.GTRenderer;
import org.geotools.renderer.label.LabelCacheImpl;
import org.geotools.renderer.lite.StreamingRenderer;
import org.geotools.styling.Stroke;
import org.geotools.styling.*;
import org.opengis.filter.FilterFactory2;
import org.opengis.referencing.crs.CoordinateReferenceSystem;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * Geo图片工具类
 *
 * @author hxd
 */
public class GeoImageUtil {

    /**
     * Layer转png
     * 根据四至坐标、长、宽像素获取地图内容，并生成图片
     *
     * @param layer   图层
     * @param bbox    四至坐标
     * @param _xy     长、宽
     * @param imgPath 输出图片路径
     */
    public static void layerToPng(Layer layer, double[] bbox, int[] _xy, String imgPath) throws IOException {
        // 四至坐标
        double x1 = bbox[0], y1 = bbox[1], x2 = bbox[2], y2 = bbox[3];
        // 输出图片长、宽
        int width = _xy[0], height = _xy[1];
        // 设置输出范围
        CoordinateReferenceSystem crs = DefaultGeographicCRS.WGS84;
        ReferencedEnvelope mapArea = new ReferencedEnvelope(x1, x2, y1, y2, crs);
        // 初始化渲染器
        StreamingRenderer sr = new StreamingRenderer();
        MapContent map = new MapContent();
        map.addLayer(layer);
        sr.setMapContent(map);
        // 初始化输出图像
        BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics g = bi.getGraphics();
        ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        Rectangle rect = new Rectangle(0, 0, width, height);
        // 绘制地图
        sr.paint((Graphics2D) g, rect, mapArea);
        // 将BufferedImage变量写入文件中。
        ImageIO.write(bi, "png", new File(imgPath));
    }

    /**
     * shapefile生成png
     *
     * @param shapefile shapefile文件
     * @param imgPath   生成图片路径
     */
    public static void shpToPng(String shapefile, String imgPath) throws IOException {
        // 获取shp FeatureCollection
        SimpleFeatureCollection fc = FeatureUtil.shpToFeatureCollection(shapefile);
        MapContent mapContent = new MapContent();
        ReferencedEnvelope bounds = fc.getBounds();
        // 默认1经纬度=100像素，即1像素=0.01经纬度，间隔约1km
        int height = (int) ((bounds.getHeight() * 100));
        int width = (int) ((bounds.getWidth() * 100));
        mapContent.getViewport().setMatchingAspectRatio(true);
        mapContent.getViewport().setScreenArea(new Rectangle(Math.round(width), Math.round(height)));
        mapContent.getViewport().setBounds(bounds);

        mapContent.setTitle("Quickstart");
        StyleFactory sf = CommonFactoryFinder.getStyleFactory();
        FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2();
        // 默认填充颜色BLUE，透明度0.7
        Fill fill = sf.fill(null, ff.literal(Color.BLUE), ff.literal(0.7));
        Stroke stroke = sf.createStroke(ff.literal("#ffffff"), ff.literal(0), ff.literal(0));
        Symbolizer symbolizer = sf.createPolygonSymbolizer(stroke, fill, "the_geom");
        FeatureTypeStyle fts = sf.createFeatureTypeStyle();
        Rule rule = sf.createRule();
        rule.symbolizers().add(symbolizer);
        fts.rules().add(rule);
        Style style = sf.createStyle();
        style.featureTypeStyles().add(fts);
        Layer layer = new FeatureLayer(fc, style);
        mapContent.addLayer(layer);

        File outputFile = new File(imgPath);
        FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
        ImageOutputStream outputImageFile = ImageIO.createImageOutputStream(fileOutputStream);
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = bufferedImage.createGraphics();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        Rectangle outputArea = new Rectangle(width, height);
        GTRenderer renderer = new StreamingRenderer();
        LabelCacheImpl labelCache = new LabelCacheImpl();
        Map<Object, Object> hints = renderer.getRendererHints();
        if (hints == null) {
            hints = new HashMap<>();
        }
        hints.put(StreamingRenderer.LABEL_CACHE_KEY, labelCache);
        renderer.setRendererHints(hints);
        renderer.setMapContent(mapContent);
        renderer.paint(g2d, outputArea, bounds);
        ImageIO.write(bufferedImage, "png", outputImageFile);
    }
}
